package com.cloud.pole.common.util;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.persistence.Id;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * 实体类相关工具类
 * 解决问题： 1、快速对实体的常驻字段，如：crtUser、crtHost、updUser等值快速注入
 *
 * @version 1.0
 * @since 1.7
 */
public class EntityUtils {
    /**
     * 快速将bean的crtUser、crtHost、crtTime、updUser、updHost、updTime附上相关值
     *
     * @param entity 实体bean
     */
    public static <T> void setCreatAndUpdatInfo(T entity) {
        setCreateInfo(entity);
        setUpdatedInfo(entity);
    }

    /**
     * 快速将bean的crtUser、crtHost、crtTime附上相关值
     *
     * @param entity 实体bean
     */
    public static <T> void setCreateInfo(T entity) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String hostIp = "";
        String name = "";
        String id = "";
        if (request != null) {
            hostIp = String.valueOf(request.getHeader("userHost"));
            name = String.valueOf(request.getHeader("userName"));
            name = URLDecoder.decode(name);
            id = String.valueOf(request.getHeader("userId"));
        }
        // 默认属性
        String[] fields = {"crtName", "crtUser", "crtHost", "crtTime"};
        Field field = ReflectionUtils.getAccessibleField(entity, "crtTime");
        // 默认值
        Object[] value = null;
        if (field != null && field.getType().equals(Date.class)) {
            value = new Object[]{name, id, hostIp, new Date()};
        }
        // 填充默认属性值
        setDefaultValues(entity, fields, value);
    }

    /**
     * 快速将bean的updUser、updHost、updTime附上相关值
     *
     * @param entity 实体bean
     */
    public static <T> void setUpdatedInfo(T entity) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String hostIp = "";
        String name = "";
        String id = "";
        if (request != null) {
            hostIp = String.valueOf(request.getHeader("userHost"));
            name = String.valueOf(request.getHeader("userName"));
            name = URLDecoder.decode(name);
            id = String.valueOf(request.getHeader("userId"));
        }
        // 默认属性
        String[] fields = {"updName", "updUser", "updHost", "updTime"};
        Field field = ReflectionUtils.getAccessibleField(entity, "updTime");
        Object[] value = null;
        if (field != null && field.getType().equals(Date.class)) {
            value = new Object[]{name, id, hostIp, new Date()};
        }
        // 填充默认属性值
        setDefaultValues(entity, fields, value);
    }

    /**
     * 依据对象的属性数组和值数组对对象的属性进行赋值
     *
     * @param entity 对象
     * @param fields 属性数组
     * @param value  值数组
     */
    private static <T> void setDefaultValues(T entity, String[] fields, Object[] value) {
        for (int i = 0; i < fields.length; i++) {
            String field = fields[i];
            if (ReflectionUtils.hasField(entity, field)) {
                ReflectionUtils.invokeSetter(entity, field, value[i]);
            }
        }
    }

    /**
     * 根据主键属性，判断主键是否值为空
     *
     * @param entity
     * @param field
     * @return 主键为空，则返回false；主键有值，返回true
     * @author 王浩彬
     * @date 2016年4月28日
     */
    public static <T> boolean isPKNotNull(T entity, String field) {
        if (!ReflectionUtils.hasField(entity, field)) {
            return false;
        }
        Object value = ReflectionUtils.getFieldValue(entity, field);
        return value != null && !"".equals(value);
    }


    /**
     * 获取系统当前时间（返回Date类型）
     *
     * @return time
     */
    public static Date findSystemTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date time = null;
        try {
            time = sdf.parse(sdf.format(new Date()));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return time;
    }

    /**
     * 获取系统当前时间的往后30分钟时间（返回Date类型）
     *
     * @return time
     */
    public static Date endSystemTime(Date systemTime) {

        long curren = systemTime.getTime();
        curren += 30 * 60 * 1000;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date time = null;
        try {
            time = sdf.parse(sdf.format(new Date(curren)));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return time;
    }


    /**
     * 根据主键属性，给主键设置IdWorkerId
     *
     * @param entity
     * @return 主键为空，则返回false；主键有值，返回true
     */
    public static <T> void setPk2IdWorkder(T entity) {
        Field[] fields = entity.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (AnnotationUtils.getAnnotation(field, Id.class) != null) {
                field.setAccessible(true);
                if (field != null && field.getType().equals(Integer.class)) {
                    throw new RuntimeException("标识有@id注解的主键不允许为Integer类型!");
                }
                try {

                    if (field != null && field.getType().equals(Long.class)) {
                        field.set(entity, IdWorker.getId());
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("标识有@id注解的主键设值出值!");
                } finally {
                    field.setAccessible(false);
                }
                break;
            }
        }
    }

}
